import {
  ParameterObjectType,
  pickedFaceData,
  pickedLineData,
  pickedVertexData,
} from '@amcax/base';
import { Picker3D } from '@amcax/renderer';
import { PickInputRJSFFormat } from '../../../../../common/components/command-form/constants';
import { MinCommonFormData, MinCommonParams } from './types';

export const center = {
  title: '位置',
  type: 'array',
  items: {
    type: 'string',
    enum: [],
  },
  format: PickInputRJSFFormat.MultiPickVertex,
  uniqueItems: true,
};

export const vector = {
  title: '方向',
  type: 'string',
  format: PickInputRJSFFormat.PickDirection,
};

export const reverseDir = {
  title: '反向',
  type: 'boolean',
  default: false,
};

export const diameter = {
  title: '主直径',
  type: 'number',
  format: ParameterObjectType.Length,
};

export const mode = {
  title: '限制类型',
  type: 'string',
  default: 'distance',
  oneOf: [
    {
      type: 'string',
      title: '盲孔',
      const: 'distance',
    },
    {
      type: 'string',
      title: '直到下一个',
      const: 'next',
    },
    {
      type: 'string',
      title: '直到最后',
      const: 'last',
    },
    {
      type: 'string',
      title: '直到几何图形',
      const: 'specify',
    },
  ],
};

export const surface = {
  title: '限制',
  type: 'string',
  format: PickInputRJSFFormat.PickSurface,
};

export const offset = {
  title: '偏移',
  type: 'number',
  format: ParameterObjectType.Length,
};

export const bottomType = {
  title: '底部类型',
  type: 'string',
  default: '-',
  oneOf: [
    {
      type: 'string',
      title: '平面',
      const: '-',
    },
    {
      type: 'string',
      title: 'V型底',
      const: 'v',
    },
  ],
};

export const angle = {
  title: '角度',
  type: 'number',
  default: 120,
  minimum: 0,
  maximum: 180,
  format: ParameterObjectType.Angle,
};

export const depthOption = {
  title: '主深度选项',
  type: 'string',
  default: 'withoutVBottom',
  oneOf: [
    {
      type: 'string',
      title: '直到肩部',
      const: 'withoutVBottom',
    },
    {
      type: 'string',
      title: '直到端部',
      const: 'withVBottom',
    },
  ],
};

export const depth = {
  title: '主深度',
  type: 'number',
  format: ParameterObjectType.Length,
};

export const locationOption = {
  title: '锥形孔定位点',
  type: 'string',
  default: 'bottom',
  oneOf: [
    {
      type: 'string',
      title: '底部',
      const: 'bottom',
    },
    {
      type: 'string',
      title: '顶部',
      const: 'upper',
    },
  ],
};

export const angle2 = {
  title: '锥形孔角度',
  type: 'number',
  default: 30,
  format: ParameterObjectType.Angle,
};

export const locationOptionForCounterbored = {
  title: '沉头孔定位点',
  type: 'string',
  default: 'bottom',
  oneOf: [
    {
      type: 'string',
      title: '末端',
      const: 'bottom',
    },
    {
      type: 'string',
      title: '中间',
      const: 'middle',
    },
  ],
};
export const diameter2 = {
  title: '沉头孔直径',
  type: 'number',
  format: ParameterObjectType.Length,
};

export const hatDepth = {
  title: '沉头孔深度',
  type: 'number',
  format: ParameterObjectType.Length,
};

export const sunkOption = {
  title: '埋头孔模式',
  type: 'string',
  default: 'depthAngle',
  oneOf: [
    {
      type: 'string',
      title: '深度和角度',
      const: 'depthAngle',
    },
    {
      type: 'string',
      title: '深度和直径',
      const: 'depthDiameter',
    },
    {
      type: 'string',
      title: '角度和直径',
      const: 'angleDiameter',
    },
  ],
};

export const diameter2ForCountersunk = {
  title: '埋头孔直径',
  type: 'number',
  format: ParameterObjectType.Length,
};
export const angle2ForCountersunk = {
  title: '埋头孔角度',
  type: 'number',
  default: 90,
  minimum: 0,
  maximum: 180,
  format: ParameterObjectType.Angle,
};
export const hatDepthForCountersunk = {
  title: '埋头孔深度',
  type: 'number',
  format: ParameterObjectType.Length,
};

export const locationOptionForCounterdrilled = {
  title: '倒钻孔定位点',
  type: 'string',
  default: 'bottom',
  oneOf: [
    {
      type: 'string',
      title: '末端',
      const: 'bottom',
    },
    {
      type: 'string',
      title: '中间',
      const: 'middle',
    },
  ],
};

export const drilledOption = {
  title: '倒钻孔模式',
  type: 'string',
  default: 'withoutSunkDiameter',
  oneOf: [
    {
      type: 'string',
      title: '无埋头孔直径',
      const: 'withoutSunkDiameter',
    },
    {
      type: 'string',
      title: '埋头孔直径',
      const: 'withSunkDiameter',
    },
  ],
};

export const diameter2ForCounterdrilled = {
  title: '倒钻孔直径',
  type: 'number',
  format: ParameterObjectType.Length,
};

export const angle2ForCounterdrilled = {
  title: '倒钻孔角度',
  type: 'number',
  default: 90,
  minimum: 0,
  maximum: 180,
  format: ParameterObjectType.Angle,
};

export const hatDepthForCounterdrilled = {
  title: '倒钻孔深度',
  type: 'number',
  format: ParameterObjectType.Length,
};

export const diameter3 = {
  title: '下沉直径',
  type: 'number',
  format: ParameterObjectType.Length,
};

export const getMinimumCommonFields = (formData: MinCommonFormData) => {
  return {
    center,
    vector,
    reverseDir,
    diameter,
    mode,
    surface: formData.mode === 'specify' ? surface : null,
    offset: formData.mode !== 'distance' ? offset : null,
    bottomType,
    angle: formData.bottomType === 'v' ? angle : null,
    depthOption: formData.bottomType === 'v' ? depthOption : null,
    depth: formData.mode === 'distance' ? depth : null,
  };
};

export const initFormDataWithProps = async (
  params: MinCommonParams,
  initEditDependency: (pickIds: string[]) => Promise<void>,
  picker: Picker3D,
): Promise<MinCommonFormData> => {
  // make sure center is an array of string
  const center = [params.center].flat();
  const {
    vector,
    reverseDir,
    diameter,
    mode,
    surface,
    offset,
    bottomType,
    angle,
    depthOption,
    depth,
  } = params;

  await initEditDependency(
    [...center, vector, surface].filter((id) => id != null),
  );

  return {
    center: center.map(
      (c) => picker.generatePickObjByPickID(c) as pickedVertexData,
    ),
    vector: picker.generatePickObjByPickID(vector) as
      | pickedFaceData
      | pickedLineData,
    reverseDir,
    diameter,
    mode,
    surface: picker.generatePickObjByPickID(surface) as pickedFaceData,
    offset,
    bottomType,
    angle: angle || 120,
    depthOption: depthOption || 'withoutVBottom',
    depth,
  };
};

export const getMinimumCommonParamsForCommand = (
  formData: MinCommonFormData,
): MinCommonParams => ({
  center: formData.center?.map((c) => c.vertexId),
  vector:
    (formData.vector as pickedFaceData)?.meshId ||
    (formData.vector as pickedLineData)?.edgeId,
  reverseDir: formData.reverseDir,
  diameter: formData.diameter,
  mode: formData.mode,
  surface: formData.surface?.meshId,
  offset: formData.offset,
  bottomType: formData.bottomType,
  angle: formData.bottomType === 'v' ? formData.angle : 0,
  depthOption: formData.depthOption,
  depth: formData.depth,
});

export const minimumFormValidation = (formData: MinCommonFormData) => {
  if (!formData.center || formData.center.length === 0 || !formData.diameter) {
    return false;
  }
  if (formData.mode === 'specify' && !formData.surface) {
    return false;
  }
  if (formData.mode === 'distance' && !formData.depth) {
    return false;
  }
  if (formData.bottomType === 'v' && !formData.angle) {
    return false;
  }

  return true;
};
